package com.bruce.ai.alibaba.agentcard.discovery.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.time.Duration;

/**
 * A2A客户端配置类
 * 支持通过application.properties或application.yml进行配置
 */
@Component
@ConfigurationProperties(prefix = "a2a.client")
public class A2AClientConfig {
    
    /**
     * 连接超时时间（毫秒）
     */
    private long connectTimeoutMs = 5000;
    
    /**
     * 读取超时时间（毫秒）
     */
    private long readTimeoutMs = 30000;
    
    /**
     * 写入超时时间（毫秒）
     */
    private long writeTimeoutMs = 30000;
    
    /**
     * 最大重试次数
     */
    private int maxRetries = 3;
    
    /**
     * 重试间隔基数（毫秒）
     */
    private long retryBaseDelayMs = 1000;
    
    /**
     * 重试间隔最大值（毫秒）
     */
    private long retryMaxDelayMs = 10000;
    
    /**
     * 连接池最大连接数
     */
    private int maxConnections = 50;
    
    /**
     * 每个路由的最大连接数
     */
    private int maxConnectionsPerRoute = 10;
    
    /**
     * 连接存活时间（毫秒）
     */
    private long connectionKeepAliveMs = 60000;
    
    /**
     * 熔断器失败阈值
     */
    private int circuitBreakerFailureThreshold = 5;
    
    /**
     * 熔断器恢复超时时间（毫秒）
     */
    private long circuitBreakerRecoveryTimeoutMs = 60000;
    
    /**
     * 是否启用熔断器
     */
    private boolean circuitBreakerEnabled = true;
    
    /**
     * 是否启用重试机制
     */
    private boolean retryEnabled = true;
    
    /**
     * 默认用户代理
     */
    private String userAgent = "A2AClient/1.0";
    
    /**
     * 认证类型 (NONE, BEARER, API_KEY, OAUTH2)
     */
    private AuthType authType = AuthType.NONE;
    
    /**
     * API密钥（当authType为API_KEY时使用）
     */
    private String apiKey;
    
    /**
     * Bearer Token（当authType为BEARER时使用）
     */
    private String bearerToken;
    
    /**
     * OAuth2配置
     */
    private OAuth2Config oauth2 = new OAuth2Config();
    
    /**
     * OAuth2 Token（当authType为OAUTH2时使用）
     */
    private String oauth2Token;
    
    /**
     * 健康检查超时时间（毫秒）
     */
    private long healthCheckTimeoutMs = 5000;
    
    /**
     * 最大空闲连接数
     */
    private int maxIdleConnections = 5;
    
    /**
     * 连接保持活跃时间（毫秒）
     */
    private long keepAliveDurationMs = 300000;
    
    // Getters and Setters
    public long getConnectTimeoutMs() {
        return connectTimeoutMs;
    }
    
    public void setConnectTimeoutMs(long connectTimeoutMs) {
        this.connectTimeoutMs = connectTimeoutMs;
    }
    
    public long getReadTimeoutMs() {
        return readTimeoutMs;
    }
    
    public void setReadTimeoutMs(long readTimeoutMs) {
        this.readTimeoutMs = readTimeoutMs;
    }
    
    public long getWriteTimeoutMs() {
        return writeTimeoutMs;
    }
    
    public void setWriteTimeoutMs(long writeTimeoutMs) {
        this.writeTimeoutMs = writeTimeoutMs;
    }
    
    public int getMaxRetries() {
        return maxRetries;
    }
    
    public void setMaxRetries(int maxRetries) {
        this.maxRetries = maxRetries;
    }
    
    public long getRetryBaseDelayMs() {
        return retryBaseDelayMs;
    }
    
    public void setRetryBaseDelayMs(long retryBaseDelayMs) {
        this.retryBaseDelayMs = retryBaseDelayMs;
    }
    
    public long getRetryMaxDelayMs() {
        return retryMaxDelayMs;
    }
    
    public void setRetryMaxDelayMs(long retryMaxDelayMs) {
        this.retryMaxDelayMs = retryMaxDelayMs;
    }
    
    public int getMaxConnections() {
        return maxConnections;
    }
    
    public void setMaxConnections(int maxConnections) {
        this.maxConnections = maxConnections;
    }
    
    public int getMaxConnectionsPerRoute() {
        return maxConnectionsPerRoute;
    }
    
    public void setMaxConnectionsPerRoute(int maxConnectionsPerRoute) {
        this.maxConnectionsPerRoute = maxConnectionsPerRoute;
    }
    
    public long getConnectionKeepAliveMs() {
        return connectionKeepAliveMs;
    }
    
    public void setConnectionKeepAliveMs(long connectionKeepAliveMs) {
        this.connectionKeepAliveMs = connectionKeepAliveMs;
    }
    
    public int getCircuitBreakerFailureThreshold() {
        return circuitBreakerFailureThreshold;
    }
    
    public void setCircuitBreakerFailureThreshold(int circuitBreakerFailureThreshold) {
        this.circuitBreakerFailureThreshold = circuitBreakerFailureThreshold;
    }
    
    public long getCircuitBreakerRecoveryTimeoutMs() {
        return circuitBreakerRecoveryTimeoutMs;
    }
    
    public void setCircuitBreakerRecoveryTimeoutMs(long circuitBreakerRecoveryTimeoutMs) {
        this.circuitBreakerRecoveryTimeoutMs = circuitBreakerRecoveryTimeoutMs;
    }
    
    public boolean isCircuitBreakerEnabled() {
        return circuitBreakerEnabled;
    }
    
    public void setCircuitBreakerEnabled(boolean circuitBreakerEnabled) {
        this.circuitBreakerEnabled = circuitBreakerEnabled;
    }
    
    public boolean isRetryEnabled() {
        return retryEnabled;
    }
    
    public void setRetryEnabled(boolean retryEnabled) {
        this.retryEnabled = retryEnabled;
    }
    
    public String getUserAgent() {
        return userAgent;
    }
    
    public void setUserAgent(String userAgent) {
        this.userAgent = userAgent;
    }
    
    public AuthType getAuthType() {
        return authType;
    }
    
    public void setAuthType(AuthType authType) {
        this.authType = authType;
    }
    
    public String getApiKey() {
        return apiKey;
    }
    
    public void setApiKey(String apiKey) {
        this.apiKey = apiKey;
    }
    
    public String getBearerToken() {
        return bearerToken;
    }
    
    public void setBearerToken(String bearerToken) {
        this.bearerToken = bearerToken;
    }
    
    public OAuth2Config getOauth2() {
        return oauth2;
    }
    
    public void setOauth2(OAuth2Config oauth2) {
        this.oauth2 = oauth2;
    }
    
    public String getOauth2Token() {
        return oauth2Token;
    }
    
    public void setOauth2Token(String oauth2Token) {
        this.oauth2Token = oauth2Token;
    }
    
    public long getHealthCheckTimeoutMs() {
        return healthCheckTimeoutMs;
    }
    
    public void setHealthCheckTimeoutMs(long healthCheckTimeoutMs) {
        this.healthCheckTimeoutMs = healthCheckTimeoutMs;
    }
    
    public int getMaxIdleConnections() {
        return maxIdleConnections;
    }
    
    public void setMaxIdleConnections(int maxIdleConnections) {
        this.maxIdleConnections = maxIdleConnections;
    }
    
    public long getKeepAliveDurationMs() {
        return keepAliveDurationMs;
    }
    
    public void setKeepAliveDurationMs(long keepAliveDurationMs) {
        this.keepAliveDurationMs = keepAliveDurationMs;
    }
    
    public Duration getConnectTimeout() {
        return Duration.ofMillis(connectTimeoutMs);
    }
    
    public Duration getReadTimeout() {
        return Duration.ofMillis(readTimeoutMs);
    }
    
    public Duration getWriteTimeout() {
        return Duration.ofMillis(writeTimeoutMs);
    }
    
    public enum AuthType {
        NONE, BEARER, API_KEY, OAUTH2
    }
    
    public static class OAuth2Config {
        private String clientId;
        private String clientSecret;
        private String tokenUrl;
        private String scope;
        
        // Getters and Setters
        public String getClientId() {
            return clientId;
        }
        
        public void setClientId(String clientId) {
            this.clientId = clientId;
        }
        
        public String getClientSecret() {
            return clientSecret;
        }
        
        public void setClientSecret(String clientSecret) {
            this.clientSecret = clientSecret;
        }
        
        public String getTokenUrl() {
            return tokenUrl;
        }
        
        public void setTokenUrl(String tokenUrl) {
            this.tokenUrl = tokenUrl;
        }
        
        public String getScope() {
            return scope;
        }
        
        public void setScope(String scope) {
            this.scope = scope;
        }
    }
}